import model
import validation

class Data:
    '''Class for managing models.'''
    
    rules = [] #this is the validation rules for creating and updating.
    
    Table = None # this is the class that we are manipulating
    
    def get_all(self, where=None, order_by=None):
        '''Retrieves all objects of the 'Table' type.'''
        db = model.getDB()
        
        if filter:
            query = model.filter(db.query(self.Table), where)
            if not isinstance(order_by, type(None)):
                query = query.order_by(order_by)
            results = query.all()
        else:
            query = db.query(self.Table)
            if not isinstance(order_by, type(None)):
                query = query.order_by(order_by)
            results = query.all()
        
        return [x.to_dict() for x in results]
    
    def get(self, id):
        '''Retrieve a single object of the 'Table' type by id.'''
        db = model.getDB()
        results = db.query(self.Table).filter(self.Table.id == id).first()
        if results:
            return results.to_dict()
        else:
            return None
    
    def create(self, **kw): #name, description=None, time_estimate=None, loc_estimate=None):
        '''Creates an object of type 'Table'.'''
        # validate data
        data = {}
        data.update(kw)
        errors = validation.validate(self.rules, data)
        if errors:
            return errors
        
        # create the object
        obj = self.Table()
        for key in data:
            if hasattr(obj, key):
                setattr(obj, key, data[key])
        
        # save object
        db = model.getDB()
        db.add(obj)
        db.commit()

        # return task.id
        return obj.id
    
    def update(self, id, **kw): #name=None, description=None, time_estimate=None, loc_estimate=None):
        '''Updates an existing task.'''
        db = model.getDB()
        #try to find the obj by id
        obj = db.query(self.Table).filter(self.Table.id == id).first()
        if not obj:
            return False
        
        #validate the datadata
        data = obj.to_dict()
        data.update(kw) #TODO what about None passed in
        errors = validation.validate(self.rules, data)
        if errors:
            return errors
        
        #if we succeeded validation then update only the keys passed in
        for key in kw:
            if hasattr(obj, key):
                setattr(obj, key, data[key])
        
        #commit the changes
        db.commit()
        
        return True

    def remove(self, id):
        '''Deletes a task permanently.'''
        db = model.getDB()
        
        #try to find the obj by id
        obj = db.query(self.Table).filter(self.Table.id == id).first()
        
        if obj == None:
            return True
        
        db.delete(obj)
        
        db.commit()
        
        return True
    
    